package cn.getech.data.development.entity;

import cn.getech.data.development.dto.JobNodeConfigDto;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;
import java.util.*;

/**
 * 任务配置的枚举
 *
 * @author zenith
 */
@Slf4j
@Data
public class JobNodeConfig implements Serializable {

    private Integer jobNodeId;

    //调度设置_类型  0不重复 1重复
    private Integer schedule_type;

    private Integer scheduleOrInterval;

    private String expression;
    private String rangerUserName;
    private String rangerUserPassword;
    /***
     * 数据接入和推送模块
     */

    //输入设置_数据源连接类型
    private Integer input_connect_type;
    //输入设置_数据源连接
    private Integer input_connect_id;

    //输入设置_数据源连接名称
    private String input_connect_name;
    //输入设置_输入方式
    private String input_input_type;
    //输入设置_输入内容
    private String input_input_content;

    //输入设置_数据库名称
    private String input_db_name;
    //输入设置_表名称
    private String input_table_name;

    //输入设置_文件位置
    private String input_file_position;

    //输入设置_数据分区
    private String input_data_partition;

    //输入设置_是否设置JDBC参数 0:不设置 1：设置
    private Integer isSetJdbcParam;

    //输入设置_JDBC连接参数
    private List<JobNodeConfJdbcParam> jobNodeConfJdbcParamList;


    //输出设置_数据源连接类型
    private Integer output_connect_type;
    //输出设置_数据源连接
    private Integer output_connect_id;
    //输出设置_数据源连接名称
    private String output_connect_name;
    //输出设置_数据库名称
    private String output_db_name;
    //输出设置_表名称
    private String output_table_name;
    //输出设置_写入模式
    private String output_write_model;
    //输出设置_数据分区
    private String output_data_partition;
    //输出设置_前置语句
    private String output_pre_statment;
    //输出设置_后置语句
    private String output_fix_statment;
    //数据库表名
    private String database_tablename;



    //高级设置_文件数(期望最大文件数)
    private String hight_file_num;
    //高级设置_并发数(期望最大并发数)
    private String hightMaxConcurrent;

    //Ftp文件位置
    private String ftpFileLocation;
    //ftp数据源接入的时候,是否逐行解析
    private Integer nonStandardFormat;

    //是否开启循环取数
    private Integer isOpenLoodAccess;
    //循环取数条数
    private Integer batchSize;
    //循环 取数起始标志
    private String beginGDA;
    //循环取数结束标志
    private String endGDA;
    //循环取数停止标志
    private String stopSign;
    //循环取数停止标志的值
    private String stopSignVal;
    //sap的输出设置_表名称  可以为空
    private List<String> sap_output_table_name;
    //SAP数据源配置信息,json字符串，和数据源原有信息分离
    private SapConnectField sapConnectFieldInfo;
    /***
     * SQL计算
     */
    private String sql_statment;
    /***
     * 本次任务的输出表ids
     */
    private List<String> jobOutPutTableIds;

    private List<String> jobOutPutTableNames;

    /***
     * 优先级配置  高、中、低
     */
    private String priorityConfig;


    /***
     * 系统参数--工作流
     */
    private List<Map<String,Object>> sysParam;

    /***
     * 系统参数--节点
     */
    private List<JSONObject> nodeParam;



    /***
     * 是否设置超时 0：不设置  1：设置
     */
    private Integer isOpenOutHours;
    /***
     * 超时时间 单位分钟
     */
    private Integer outHours;



    /***
     * 程序执行
     */
    //程序主类
    private String base_proc_main_class;
    //输入路径
    private String base_proc_main_in;
    //输出路径
    private String base_proc_main_out;
    //程序参数
    private String base_proc_main_args;
    //程序文件地址
    private String base_proc_main_file;

    //spark.driver.memory
    private String  resource_dm;
    //spark.driver.cores
    private String resource_dc;
    //spark.executor.memory
    private String  resource_em;
    //spark.executor.cores
    private String  resource_ec;

    //是否启用调度时间范围配置  0：不启用  1：启用
    private Integer isDurTime;
    private String startTime;
    private String endTime;

    //是否开启动态时间参数 自动的时间 0：不启用  1：启用
    private Integer isOpenTime;
    private String sysStartTime;
    private String sysEndTime;
    private Double sysDurTime;
    private String timeFormat; //时间格式

    //是否启用重试配置  0：不启用  1：启用
    private Integer isRetry;
    private Integer reTryMax;
    private Integer reTryInterval;

    //是否开启分页数(0:不开启,1开启)
    private Integer startPageCount;
    //当前页码
    private Integer pageNum;
    //当前页码记录数
    private Integer pageSize;
    //结束标识
    private String endName;
    //是否开启自增
    private Integer enableIncresement;
    //输出的同步任务存储引擎
    private Integer output_storage_engine_type;
    //查询引擎
    private Integer query_engine;
    /******算法开发前端交互字段-start*********/
    //模型类型;
    private String modelTypeId;
    //模型类型名称;
    private String modelTypeName;
    //算法类型;
    private Integer algorithmTypeId;
    //算法类型的名字;
    private String algorithmTypeName;
    //模型id;
    private Integer modelId;
    //模型name;
    private String  modelName;
    //预测输入数据库名称;
    private String inputPreDbName;
    //预测输入数据库id;
    private Integer inputPreDbId;
    //预测输入表的名称;
    private String inputPreTableName;
    //预测输入表id
    private Integer inputPreTableId;
    //预测输出数据库名称;
    private String outputPreDbName;
    //预测输出数据库id;
    private Integer outputPreDbId;
    //预测输出表的名称;
    private String outputPreTableName;
    //预测输出表id
    private Integer outputPreTableId;
    //预测结果字段映射;
    private List<Map<String,Object>> preResultInfos;

    /******es的数据源数据同步-start*********/
    private String esSqlCondition;//es的检索条件
    private String esIndex;//索引
    private String esIndexType;//索引类型
    private Long esPageSize;//分页大小
    private Long esPageTime;//单位s

    /******webservice支持raw-start*********/
    private Integer reqType;//1.xml 2.json
    private String webserviceText;//xml请求数据
    private Integer resType;//1.xml 2.json
    private String anaTableNameUrl;//xml解析表的路径，按照.的路径
    private Integer olderRequestType;// 1.GET   2.POST-urlencoded  3.POST-raw

    //配置方式:cronType (1:手动配置 2：crontab表达式)
    //crontab表达式：cronUrl
    private Integer cronType;
    private String cronUrl;

    //FTP文件格式
    private String ftpFileType;
    //FTP文件名匹配方式 1：普通匹配  2：正则匹配  3：日期动态参数配置
    private Integer ftpFileMatchType;
    //FTP文件名
    private String ftpFileName;



    /**
     * 配置的任务类型，0：节点的配置  1：菜单目录对应的配置（全局配置）
     */
    private Integer jobType;

    public static JobNodeConfig listToJobNodeConfig(List<JobNodeConf> list) {
        if (list == null)
            return null;

        Map<String,Object> map=new HashMap<>();
        for (JobNodeConf conf:list
        ) {
            map.put(conf.getKey(),conf.getValue());
        }
        return mapToJobNodeConfig(map);
    }


    public static List<JobNodeConf> jobNodeConfigTolist(JobNodeConfig jobNodeConfig) {
        if(jobNodeConfig == null)
            return null;

        Map<Object,Object> map= new org.apache.commons.beanutils.BeanMap(jobNodeConfig);
        List<JobNodeConf> list=new ArrayList<>();
        for (Object k:map.keySet()) {
            if(map.get(k) !=null && !("class".equals(k))) {
                JobNodeConf conf = new JobNodeConf();
                conf.setKey(String.valueOf(k));
                //工作流和节点的系统参数
                if("sysParam".equals(String.valueOf(k))
                        || "nodeParam".equals(String.valueOf(k))
                        || "jobOutPutTableIds".equals(String.valueOf(k))){
                    conf.setValue(JSONObject.toJSONString(map.get(k)));
                }  else{
                    conf.setValue(map.get(k).toString());
                }
                if("preResultInfos".equals(String.valueOf(k)) || "jobNodeConfJdbcParamList".equals(String.valueOf(k))){
                    conf.setValue(JSONObject.toJSONString(map.get(k)));
                }
                conf.setJobNodeId(jobNodeConfig.getJobNodeId());
                conf.setJobType(jobNodeConfig.getJobType());
                list.add(conf);
            }else if(null == map.get(k)){
                JobNodeConf conf = new JobNodeConf();
                conf.setKey(String.valueOf(k));
                conf.setValue(null);
                conf.setJobNodeId(jobNodeConfig.getJobNodeId());
                conf.setJobType(jobNodeConfig.getJobType());
                list.add(conf);
            }
        }
        return  list;

    }

    public static List<JobNodeConf> jobNodeConfigDtoTolist(JobNodeConfigDto jobNodeConfigDto) {
        if(jobNodeConfigDto == null)
            return null;

        Map<Object,Object> map= new org.apache.commons.beanutils.BeanMap(jobNodeConfigDto);
        List<JobNodeConf> list=new ArrayList<>();
        for (Object k:map.keySet()
        ) {

            if(map.get(k) !=null && !("class".equals(k))) {
                JobNodeConf conf = new JobNodeConf();
                conf.setKey(String.valueOf(k));
                //工作流和节点的系统参数
                if("sysParam".equals(String.valueOf(k))
                        || "nodeParam".equals(String.valueOf(k))
                        || "jobOutPutTableIds".equals(String.valueOf(k))){
                    conf.setValue(JSONObject.toJSONString(map.get(k)));
                } else {
                    conf.setValue(map.get(k).toString());
                }
                conf.setJobNodeId(jobNodeConfigDto.getJobNodeId());
                conf.setJobType(jobNodeConfigDto.getJobType());
                list.add(conf);
            }else if(null == map.get(k)){
                JobNodeConf conf = new JobNodeConf();
                conf.setKey(String.valueOf(k));
                conf.setValue(null);
                conf.setJobNodeId(jobNodeConfigDto.getJobNodeId());
                conf.setJobType(jobNodeConfigDto.getJobType());
                list.add(conf);
            }
        }
        return  list;

    }


    public static JobNodeConfig mapToJobNodeConfig(Map<String, Object> map) {
        if (map == null)
            return null;
        JobNodeConfig obj;
        try {
            Object nodeParam = map.get("nodeParam");
            if(null != nodeParam){
                map.remove("nodeParam");
            }
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(map));
            obj = JSON.parseObject(jsonObject.toJSONString(), new TypeReference<JobNodeConfig>(){});

            //节点的系统参数
            if(null != nodeParam){
                JSONArray jsonArray = JSONArray.parseArray(nodeParam.toString());
                if(CollectionUtil.isNotEmpty(jsonArray)){
                    List<JSONObject> nodeParam1 = new ArrayList<>();
                    for (Object o : jsonArray) {
                        if(null != o){
                            JSONObject jsonObject1 = JSONObject.parseObject(o.toString());
                            nodeParam1.add(jsonObject1);
                        }
                    }
                    obj.setNodeParam(nodeParam1);
                }
            }

            //如果是sap,其它的sapConnectFieldInfos和sap_output_table_name字段的装换
            if (obj.getSap_output_table_name()!=null&&!obj.getSap_output_table_name().equals("")&&!obj.getSap_output_table_name().equals("[]")){
                Integer length = obj.getSap_output_table_name().get(0).length();
                String name = obj.getSap_output_table_name().get(0).substring(1,length-1);
                List<String> sapNames = Arrays.asList(name.split(","));
                obj.setSap_output_table_name(sapNames);
            }
            Object sapConnectFieldInfos = map.get("sapConnectFieldInfos");
            if(null != sapConnectFieldInfos){
                //转化成对应的实体
                SapConnectField sapConnectField = JSON.parseObject(sapConnectFieldInfos.toString(), new TypeReference<SapConnectField>(){});
                obj.setSapConnectFieldInfo(sapConnectField);
            }

//            obj = JobNodeConfig.class.newInstance();
//            BeanMap beanMap = BeanMap.create(obj);
//            beanMap.putAll(map);
            return obj;
        } catch (Exception e) {
            log.error("JobNodeConfig实体转换异常！error:{}",e.getMessage());
            return null;
        }
    }




    public static Map<?, ?> jobNodeConfigToMap(JobNodeConfig jobNodeConfig) {
        if(jobNodeConfig == null)
            return null;
        return new org.apache.commons.beanutils.BeanMap(jobNodeConfig);
    }


}
